#!/usr/bin/python3.6
# -*- coding: UTF-8 -*-


import argparse
import json
import os
import platform
import shutil
import time
import zipfile
import platform
import plist as plistLib
import socket
# from biplist import *

# from PIL import Image, ImageFile
# from biplist import *

workspace_path = os.getcwd()
root_path = workspace_path[0:workspace_path.rfind(os.sep)] + os.sep
root_path = workspace_path + os.sep
define_max_length = 500
def get_host_ip():
    try:
        # Create a new socket using the given address family,
        # socket type and protocol number.
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # Connect to a remote socket at address.
        # (The format of address depends on the address family.)
        address = ("8.8.8.8", 80)
        s.connect(address)

        # Return the socket’s own address.
        # This is useful to find out the port number of an IPv4/v6 socket, for instance.
        # (The format of the address returned depends on the address family.)
        sockname = s.getsockname()
        # print(sockname)

        ip = sockname[0]
        port = sockname[1]
    finally:
        s.close()

    return ip

def parse_args():
    parser = argparse.ArgumentParser(description='hugo生成下载地址.\n')

    git_https = 'https://gitee.com/iTouchTV/ipa/raw/feature/hugo/a_upload/'
    ipd_download_http = 'http://192.168.199.201:8000/'
    ipa_location_path = root_path + 't_cosipa' + os.sep

    git_https = 'https://gitee.com/iTouchTV/hugo_app_distribute/raw/master/a_upload/'
    #ipd_download_http = 'http://172.22.1.250:9090/files/'


    ipd_download_http = 'http://%s:9090/files/'%(get_host_ip())

    desktop_path = os.path.join(os.path.expanduser('~'), 'Desktop') + os.sep
    ipa_location_path = desktop_path + 'web_workspace' + os.sep + 'resources' + os.sep
    html_location_path = desktop_path + 'web_workspace' + os.sep + 'public' + os.sep

    parser.add_argument('--icon_base_url',
                        default=git_https,
                        dest='icon_base_url',
                        help='app图片起始域名', type=str, required=False)

    parser.add_argument('--qrcode_base_url',
                        default=git_https,
                        dest='qrcode_base_url',
                        help='qrcode起始域名', type=str, required=False)

    parser.add_argument('--plist_base_url',
                        default=git_https,
                        dest='plist_base_url',
                        help='plist起始域名', type=str, required=False)

    parser.add_argument('--ipa_base_url',
                        # default='https://gitee.com/iTouchTV/ipa/raw/feature/hugo/a_upload/',
                        default=ipd_download_http,
                        # default='https://ipa-download.ddns.linkfun.top/',
                        dest='ipa_base_url',
                        help='ipa起始域名', type=str, required=False)

    parser.add_argument('--app_desc',
                        # default='1.xxxxx\n2.bbbbb\n3.ccccc\n',
                        default='',
                        dest='app_desc',
                        help='app描述（每次传入）', type=str, required=False)

    parser.add_argument('--ipa_dir',
                        default=ipa_location_path,
                        dest='ipa_dir',
                        help='ipa存放位置（cos|~/Desktop/w_ipa_sercer/）', type=str, required=False)

    parser.add_argument('--ipa_name',
                        default='t_ipa.ipa',
                        dest='ipa_name',
                        help='ipa文件名(不建议改动)', type=str, required=False)

    parser.add_argument('--log_name',
                        default='t_git_log.txt',
                        dest='log_name',
                        help='git 提交记录', type=str, required=False)

    parser.add_argument('--upload_folder_path',
                        default='a_upload' + os.sep,
                        dest='upload_folder_path',
                        help='上传资源git目录,含icon,plist等小文件(不建议改动)', type=str, required=False)

    parser.add_argument('--copy_public_path',
                        default=html_location_path,
                        dest='copy_public_path',
                        help='复制html目录', type=str, required=False)


    # os.environ['plist_res_server'] = plist_res_server
    os.environ['ipd_download_http'] = ipd_download_http
    args = parser.parse_args()
    return args


class Model(object):
    class IpaInfo(object):

        @classmethod
        def Object(self, json_text):
            t_dict = json.loads(json_text)
            t_obj = Model.IpaInfo()
            # 校验数据合法性
            if 'app_desc' not in t_dict.keys():
                t_dict['app_desc'] = ''
            t_obj.__dict__ = t_dict
            return t_obj

        def __init__(
                self,
                # plist
                CFBundleIdentifier='',
                CFBundleShortVersionString='',
                CFBundleVersion='',
                CFBundleName='',
                # embedded.mobileprovision
                ProvisionsAllDevices='',
                TeamName='',
                TeamIdentifier='',
                ProvisioningName='',
                # calc
                icon_name='',
                icon_path='',
                ipa_path='',
                date='',
                app_desc=''
        ):
            self.CFBundleIdentifier = CFBundleIdentifier
            self.CFBundleShortVersionString = CFBundleShortVersionString
            self.CFBundleVersion = CFBundleVersion
            self.CFBundleDisplayName = CFBundleName
            self.ProvisionsAllDevices = ProvisionsAllDevices
            self.TeamName = TeamName
            self.TeamIdentifier = TeamIdentifier
            self.ProvisioningName = ProvisioningName
            self.icon_name = icon_name
            self.icon_path = icon_path
            self.date = date
            self.ipa_path = ipa_path
            self.app_desc = app_desc

        def json(self):
            json_dict = self.__dict__
            json_dict['icon_name'] = ''
            json_dict['icon_path'] = ''
            json_dict['ipa_path'] = ''
            result = json.dumps(self.__dict__, ensure_ascii=False)
            return result

        def folder_path(self):
            path = self.CFBundleIdentifier + os.sep + self.CFBundleShortVersionString + os.sep  # + self.CFBundleVersion
            return path

        def identification(self):
            identification = self.CFBundleIdentifier + '_' + self.CFBundleVersion + '_' + self.CFBundleShortVersionString
            return identification

        def ipa_introduction(self):
            provisioningName = self.ProvisioningName.lower()

            if provisioningName.find("touchtvinhouse") > -1:
                provisioningName = "（企签）"
            elif provisioningName.find("ad hoc") > -1 or provisioningName.find("adhoc") > -1:
                provisioningName = "（公测）"
            else:
                provisioningName = "（测试）"
            text = '名称：%s\n版本号：%s\n构建号：%s\n签名类型:%s\n证书:%s\n' % \
                   (
                       self.CFBundleDisplayName,
                       self.CFBundleShortVersionString,
                       self.CFBundleVersion,
                       provisioningName,
                       self.ProvisioningName,
                   )
            return text

        def ipa_name(self):
            # 增加证书区分,主要是区分企签和公测包
            cur_date = int(self.CFBundleVersion)
            tag_date = int('202001171427')
            path = self.CFBundleIdentifier + '_' + self.CFBundleShortVersionString + '_' + self.CFBundleVersion + '.ipa'
            if cur_date > tag_date:
                path = '%s_%s_%s_%s.ipa' % \
                       (self.CFBundleIdentifier,
                        self.CFBundleShortVersionString,
                        self.CFBundleVersion,
                        self.TeamIdentifier)
            path = self.check_text(path)
            return path

        def relative_ipa_path(self):
            url = self.folder_path() + self.ipa_name()
            url = self.check_text(url)
            return url

        def relative_app_icon_path(self):

            path = self.CFBundleIdentifier + '_' + self.CFBundleShortVersionString + '_' + self.CFBundleVersion + '.ipa'
            url = path.replace('.ipa', '_icon.png')
            # url = self.relative_ipa_path().replace('.ipa', '_icon.png')
            url = self.check_text(url)
            return url

        def relative_app_local_icon_path(self):
            path = self.folder_path() + self.relative_app_icon_path()
            return path

        def relative_qrcode_icon_path(self):
            url = self.relative_ipa_path().replace('.ipa', '_qrcode.png')
            url = self.check_text(url)
            return url

        def relative_plist_path(self):
            url = self.relative_ipa_path().replace('.ipa', '.plist')
            url = self.check_text(url)
            return url

        def relative_md_path_bak(self):
            def generate_md5(input_string):
                import hashlib
                # 创建一个 md5 对象
                md5_hash = hashlib.md5()

                # 更新 md5 对象，必须是字节类型
                md5_hash.update(input_string.encode('utf-8'))

                # 获取十六进制的哈希值
                return md5_hash.hexdigest()

            url = self.relative_ipa_path()
            file_name = url[url.rfind(os.sep)+1:]
            md5_file_name = generate_md5(f"{file_name}{self.ProvisioningName}")
            url = url.replace(file_name,f"{md5_file_name}.md")
            url = self.check_text(url)
            return url
        def relative_md_path(self):
            url = self.relative_ipa_path().replace('.ipa', '.md')
            url = self.check_text(url)
            return url

        def relative_url(self):
            # url = self.relative_md_path().replace('.md', '') + os.sep
            # return url
            url = os.sep + 'app' + os.sep + self.relative_ipa_path().replace('.ipa', '') + os.sep
            # url = os.sep + url.replace(os.sep, '') + os.sep
            url = self.check_text(url)
            # url = url.replace('.','')
            return url

        def format_date(self):
            # 2015-11-15T10:42:51+08:00
            date_text = '0000-00-00T00:00:00+08:00'  # date_text
            try:
                build_version = self.CFBundleVersion
                if len(self.date) > 0:
                    date_text = self.date
                elif len(build_version) >= 12:
                    # 2018-01-02 12:00:00
                    self.date = '%s-%s-%sT%s:%s:00+08:00' % (
                        build_version[0:4],
                        build_version[4:6],
                        build_version[6:8],
                        build_version[8:10],
                        build_version[10:]
                    )
                    date_text = self.date
                else:
                    time_stamp = time.time()  # 当前时间的时间戳
                    local_time = time.localtime(time_stamp)  #
                    str_time = time.strftime('%Y-%m-%dT%H:%M:%S+08:00', local_time)
                    self.date = str_time
                    date_text = self.date
            except:
                pass
            print(date_text)
            return date_text

        def check_text(self, url):
            return url
            url = url.replace('~', '')
            url = url.replace('*', '')
            return url


class Ipa(object):
    def __init__(self):
        pass

    # 递归文件
    def list_files(self, path, list_name):  # 传入存储的list
        for file in os.listdir(path):
            file_path = os.path.join(path, file)
            if os.path.isdir(file_path):
                self.list_files(file_path, list_name)
            else:
                list_name.append(file_path)

    # 获取文件名
    def get_file_name(self, path):
        i = path.rfind(os.sep)
        text = path[i + 1:]
        return text

    # 读取文件
    def load_file(self, path):
        f = open(path, 'r')
        sourceInLine = f.readlines()
        lines = []
        for line in sourceInLine:
            lines.append(line)
        f.close()
        return lines
        # dataset=[]
        # for line in sourceInLine:
        #     temp1=line.strip('\n')
        #     temp2=temp1.split('\t')
        #     dataset.append(temp2)
        # return dataset

    # 保存文件
    def save_file(self, file_path, lines):

        if (os.path.exists(file_path)):
            os.remove(file_path)
        file = open(file_path, 'w')
        file.writelines(lines)
        file.close()

    # 解析plist
    def analysi_plist(self, plist_path):
        print(plist_path)
        with open(plist_path, 'rb') as fp:
            plist = plistLib.load(fp)
        # plist = readPlist(plist_path)
        print('plist:')
        print(plist)
        info = Model.IpaInfo()
        info.CFBundleIdentifier = plist['CFBundleIdentifier']
        info.CFBundleShortVersionString = plist['CFBundleShortVersionString']
        info.CFBundleVersion = plist['CFBundleVersion']
        try:
            info.CFBundleDisplayName = plist['CFBundleDisplayName']
        except:
            info.CFBundleDisplayName = 'other'

        if platform.system().lower().find('darwin') > -1:
            path = plist_path[:plist_path.rfind(os.sep)]
            cmd1 = 'cd %s' % (path)
            cmd2 = 'security cms -D -i embedded.mobileprovision'
            cmd = '%s && %s' % (cmd1, cmd2)
            result = os.popen(cmd).read()
            embedded_mobileprovision = plistLib.loads(result.encode())  # readPlistFromString(result.encode())
            info.TeamName = embedded_mobileprovision['TeamName']
            info.ProvisioningName = embedded_mobileprovision['Name']
            info.TeamIdentifier = embedded_mobileprovision['TeamIdentifier'][0]
            info.ProvisionsAllDevices = False
            if 'ProvisionsAllDevices' in embedded_mobileprovision.keys():
                info.ProvisionsAllDevices = embedded_mobileprovision['ProvisionsAllDevices']
        else:
            info.TeamName = ''
            info.ProvisioningName = ''
            info.TeamIdentifier = ''

        print('mobileprovision:')
        print(embedded_mobileprovision)

        # try:
        # except:
        #     pass
        # list = plist['CFBundleIcons']['CFBundlePrimaryIcon']['CFBundleIconName']
        # if len(list) > 0:
        #     info.icon_name = list[len(list) - 1]
        return info

    # 解压压缩包,并重定义压缩包第一层文件
    def unzip(self, zip_path, tag_path):
        if os.path.exists(tag_path):
            shutil.rmtree(tag_path)
        f = zipfile.ZipFile(zip_path, 'r')
        unzip_top_directory_name = ""
        print("解压文件: " + zip_path)
        unzip_path = tag_path[0:tag_path[0:len(tag_path) - 1].rfind(os.sep) + 1] + "tmp" + os.sep
        for file in f.namelist():
            names = file.split(os.sep)
            if len(names) > 1 and len(names[1]) > 0:
                f.extract(file, unzip_path)

            elif len(names) - 1 == 1 and len(unzip_top_directory_name) == 0:
                unzip_top_directory_name = names[0]
            else:
                pass
        f.close()
        unzip_path = unzip_path + unzip_top_directory_name
        shutil.move(unzip_path, tag_path)

    # 获取ipa包信息 并返回
    def run(self, ipa_path):
        unzip_path = root_path + 't_uzip'

        self.unzip(zip_path=ipa_path, tag_path=unzip_path)

        list_res = []
        list_plist = []
        list_png = []
        self.list_files(unzip_path, list_res)
        for path in list_res:
            lower_path = path.lower()
            if lower_path.endswith('info.plist'):
                list_plist.append(path)
            elif lower_path.endswith('.png') and lower_path.find('appicon') > 0:
                list_png.append(path)
        list_plist = sorted(list_plist, key=lambda i: len(i), reverse=False)
        # list_png = sorted(list_png, key=lambda i: len(i), reverse=False)
        info_plist = self.analysi_plist(list_plist[0])
        info_plist.ipa_path = ipa_path
        if len(list_png) > 0:
            info_plist.icon_path = list_png[len(list_png) - 1]
        return info_plist


class Template(object):
    def __init__(self, plist_template='', post_template='', output_path=''):
        self.plist_template = plist_template
        self.post_template = post_template
        self.output_path = output_path
        pass

    def copy_ipa(self, ipa_dir='', src_ipa_path='', tar_ipa_path=''):
        self.out_put_check(tar_ipa_path)
        shutil.copy(src_ipa_path, tar_ipa_path)
        print('copy ipa %s -> %s' % (src_ipa_path, tar_ipa_path))

    def copy_icon(self, src_path='', tar_path='',tar_local_path=''):
        if len(src_path) == 0:
            return
        if os.path.exists(src_path) == False:
            return
        self.out_put_check(tar_path)

        # shutil.copy(src_path, tar_path)

        # ipin.updatePNG(src_path)

        # ImageFile.LOAD_TRUNCATED_IMAGES = True
        # img = Image.open(src_path)
        # img.save(tar_path)

        if platform.system().lower().find('darwin') > -1:
            # mac os
            cmd = 'xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations %s %s' % (src_path, tar_path)
            os.system(cmd)
        else:
            shutil.copy(src_path, tar_path)

        if len(tar_local_path) > 0:
            shutil.copy(tar_path, tar_local_path)
            # 移除上传到git文件
            os.remove(tar_path)
        pass


    def make_plist(self, out_put='',
                   template_url_disp_icon='',
                   template_url_ipa='',
                   template_ipa_name='',
                   template_url_bundleid=''):
        self.out_put_check(out_put)
        ipa = Ipa()
        tmps = ipa.load_file(self.plist_template)

        plist_res_server = os.getenv("plist_res_server")
        ipd_download_http = os.getenv("ipd_download_http")
        if plist_res_server is not None:
            template_url_ipa = template_url_ipa.replace(ipd_download_http,plist_res_server)
            template_url_disp_icon = template_url_disp_icon.replace(ipd_download_http, plist_res_server)


        lines = []
        for line in tmps:
            line = line.replace('template_url_disp_icon', template_url_disp_icon)
            line = line.replace('template_url_ipa', template_url_ipa)
            line = line.replace('template_ipa_name', template_ipa_name)
            line = line.replace('template_url_bundleid', template_url_bundleid)
            lines.append(line)
        ipa.save_file(out_put, lines)
        pass

    def make_post(self,
                  out_put='',
                  template_post_page_url='',
                  template_post_name='',
                  template_post_date='',
                  template_post_desc='',
                  template_post_plist='',
                  template_post_icon='',
                  template_post_introduction='',
                  template_post_qrcode='',
                  template_post_ipa_file=''):
        self.out_put_check(out_put)
        ipa = Ipa()
        tmps = ipa.load_file(self.post_template)
        lines = []
        for line in tmps:
            line = line.replace('template_post_page_url', template_post_page_url)
            line = line.replace('template_post_name', template_post_name)
            line = line.replace('template_post_date', template_post_date)
            line = line.replace('template_post_desc', template_post_desc)
            line = line.replace('template_post_plist', template_post_plist)
            line = line.replace('template_post_icon', template_post_icon)
            line = line.replace('template_post_qrcode', template_post_qrcode)
            line = line.replace('template_post_introduction', template_post_introduction)
            line = line.replace('template_post_ipa_file', template_post_ipa_file)
            line = line.replace('template_itms_services', 'itms-services://?action=download-manifest&url=%s'%(template_post_plist))
            lines.append(line)
        ipa.save_file(out_put, lines)
        pass

    def build_all_post(self):
        pass

    def out_put_check(self, tar_ipa_path=''):
        if os.path.exists(tar_ipa_path):
            os.remove(tar_ipa_path)
        folder_path = tar_ipa_path[:tar_ipa_path.rfind(os.sep) + 1]
        if os.path.exists(folder_path) == False:
            os.makedirs(folder_path)


class Manager(object):
    def __init__(self, history_path=''):
        self.history_path = history_path
        self.list_history = self.load_cache()
        pass

    def handle_add(self, app_args, ipa_src_path=''):
        icon_base_url = app_args.icon_base_url
        qrcode_base_url = app_args.qrcode_base_url
        plist_base_url = app_args.plist_base_url
        ipa_base_url = app_args.ipa_base_url
        ipa_dir = app_args.ipa_dir
        ipa_name = app_args.ipa_name
        upload_folder_path = app_args.upload_folder_path
        app_desc = app_args.app_desc
        log_name = app_args.log_name
        # 解析ipa并获取数据
        if len(ipa_src_path) == 0:
            ipa_src_path = root_path + ipa_name
        if os.path.exists(ipa_src_path) == False:
            return None
        print('handle add:%s', ipa_src_path)
        # 读取日志
        log_src_path = root_path + log_name
        if os.path.exists(log_src_path):
            lines = Ipa().load_file(log_src_path)
            app_desc = '%s%s' % (app_desc, ''.join(lines))

        info = Ipa().run(ipa_src_path)
        print(info)

        # 创建模板工具类
        template = Template(
            plist_template=root_path + 'a_template' + os.sep + 'download.plist',
            post_template=root_path + 'a_template' + os.sep + 'post.md',
        )

        # 复制文件到指定位置
        template.copy_ipa(
            ipa_dir=ipa_dir,
            src_ipa_path=info.ipa_path,
            tar_ipa_path=ipa_dir + info.relative_ipa_path()
        )
        template.copy_icon(
            src_path=info.icon_path,
            tar_path=root_path + upload_folder_path + info.relative_app_icon_path(),
            tar_local_path=ipa_dir  + info.relative_app_local_icon_path(),
        )

        ipa_download_url = ipa_base_url + info.relative_ipa_path()
        ipa_download_icon_url = ipa_base_url + info.relative_app_local_icon_path()
        # ipa_download_icon_url = icon_base_url + info.relative_app_icon_path()
        # 生成plist
        template.make_plist(
            out_put=root_path + upload_folder_path + info.relative_plist_path(),
            template_ipa_name=info.CFBundleDisplayName,
            template_url_disp_icon=ipa_download_icon_url,
            template_url_ipa=ipa_download_url,
            template_url_bundleid=info.CFBundleIdentifier
        )

        # 生成post
        template.make_post(
            out_put=root_path + 'content' + os.sep + 'post' + os.sep + info.relative_md_path(),
            template_post_page_url=info.relative_url(),
            template_post_name=info.CFBundleDisplayName,
            template_post_icon=ipa_download_icon_url,
            template_post_date=info.format_date(),
            template_post_plist=plist_base_url + info.relative_plist_path(),
            template_post_desc=app_desc,
            template_post_introduction=info.ipa_introduction(),
            template_post_qrcode='',
            template_post_ipa_file=ipa_download_url
        )
        info.app_desc = '%s\n%s' % (info.ipa_introduction(), app_desc)

        def append_with_limit(lst, item, limit=999):

            lst.append(item)
            while len(lst) > limit:
                lst.pop(0)

        append_with_limit(self.list_history, info,limit=define_max_length)
        # self.list_history.append(info)
        self.save_cache()
        return info

    def handle_history(self, app_args):
        icon_base_url = app_args.icon_base_url
        qrcode_base_url = app_args.qrcode_base_url
        plist_base_url = app_args.plist_base_url
        ipa_base_url = app_args.ipa_base_url
        upload_folder_path = app_args.upload_folder_path

        # 创建模板工具类
        template = Template(
            plist_template=root_path + 'a_template' + os.sep + 'download.plist',
            post_template=root_path + 'a_template' + os.sep + 'post.md',
        )
        cutLines = self.cutLines(maxLine=100, lines=self.list_history, isUnique=True)
        print('create md file total:%d | all ipa data:%d' % (len(cutLines),len(self.list_history)))
        for info in cutLines:
            ipa_download_url = ipa_base_url + info.relative_ipa_path()
            ipa_download_icon_url = ipa_base_url + info.relative_app_local_icon_path()
            # ipa_download_icon_url = icon_base_url + info.relative_app_icon_path(),
            # 生成plist
            template.make_plist(
                out_put=root_path + upload_folder_path + info.relative_plist_path(),
                template_ipa_name=info.CFBundleDisplayName,
                template_url_disp_icon=ipa_download_icon_url,
                template_url_ipa=ipa_download_url,
                template_url_bundleid=info.CFBundleIdentifier
            )

            # 生成post
            template.make_post(
                out_put=root_path + 'content' + os.sep + 'post' + os.sep + info.relative_md_path(),
                template_post_page_url=info.relative_url(),
                template_post_name=info.CFBundleDisplayName,
                template_post_icon=ipa_download_icon_url,
                template_post_date=info.format_date(),
                template_post_plist=plist_base_url + info.relative_plist_path(),
                template_post_desc=info.app_desc,
                template_post_introduction=info.ipa_introduction(),
                template_post_qrcode='',
                template_post_ipa_file=ipa_download_url
            )

        # self.list_history = self.load_cache(history_path=history_path)
        return len(self.list_history)


    def cutLines(self, maxLine=500, lines=[], isUnique=False,
                 nameFilter=['KAN-KAN','unc0ver', '云端信宜app', '闲鱼', '小小影视', '爱奇艺', '腾讯视频']):
        # 保留最近100个，大于最近100个则保留，最后一个version号
        if len(lines) == 0:
            return lines
        maxNumber = maxLine
        curLineMax = maxNumber
        if len(lines) < maxNumber:
            curLineMax = len(lines) - 1
        cutLines = lines[:curLineMax]
        recordList = []


        if isUnique:
            filterList = []
            for name in nameFilter:
                filterList.append(name.upper())
            for tmp in lines[curLineMax:]:
                if tmp.CFBundleDisplayName.upper() in filterList:
                    pass
                else:
                    key = '%s%s%s' % (tmp.CFBundleIdentifier, tmp.CFBundleShortVersionString, tmp.ProvisioningName)
                    if key not in recordList:
                        cutLines.append(tmp)
                        recordList.append(key)
        return cutLines

    def load_cache(self):
        history_path = self.history_path
        lines = []

        # 读取数据
        f = open(history_path, 'r', encoding='utf-8')
        try:
            re = f.read()
            cache_dict = json.loads(re)
            list_exists = []
            # json -> object
            list_history = cache_dict['history']
            for json_text in reversed(list_history):
                obj = Model.IpaInfo.Object(json_text)
                if obj.identification() not in list_exists:
                    list_exists.append(obj.identification())
                    lines.append(obj)
        except:
            pass
        f.close()
        return lines

    def save_cache(self):
        history_path = self.history_path
        history_list = self.list_history
        # object -> json
        lines = []
        for obj in history_list:
            lines.append(obj.json())

        # 写入数据
        cache_dict = {'history': lines}
        result = json.dumps(cache_dict, ensure_ascii=False)
        f = open(history_path, 'w', encoding='utf-8')
        f.write(result)
        f.close()

    def copy_public(self, src_path, tar_path):
        if os.path.exists(tar_path):
            shutil.rmtree(tar_path)
        shutil.copytree(src_path, tar_path)
        print('copy html files %s -> %s' % (src_path, tar_path))

    def rebuild_hugo(self, workspace=''):
        public_path = workspace + 'public' + os.sep
        if os.path.exists(public_path):
            shutil.rmtree(public_path)
        cmd_1 = 'cd %s' % (workspace)
        # cmd_2 = '/usr/local/bin/hugo --verbose'
        cmd_2 = '/usr/local/bin/hugo'
        if platform.platform().lower().find('arm64-arm') > -1:
            cmd_2 = '/opt/homebrew/bin/hugo'
        cmd = '%s && %s' % (cmd_1, cmd_2)
        os.system(cmd)


    def git_commit(self, workspace='', message=''):
        if len(message) == 0:
            message = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        cmd_0 = 'cd %s' % (workspace)
        cmd_1 = 'git add .'
        cmd_2 = 'git commit -m "%s"' % (message)
        cmd_3 = 'git push'
        cmd = '%s && %s && %s && %s' % (cmd_0, cmd_1, cmd_2, cmd_3)
        os.system(cmd)
        pass

    def cos_update(self, location_path='', cos_path=''):
        if len(location_path) == 0 or len(cos_path) == 0:
            return
        pass


def main():
    startTime = time.time()

    print('run in %s system' % (platform.system()))

    # 参数
    app_args = parse_args()
    if app_args.app_desc == 'null' or app_args.app_desc == 'None':
        app_args.app_desc = ''
    app_desc = app_args.app_desc
    print(app_args)
    copy_public_path = app_args.copy_public_path
    content_output = root_path + 'content' + os.sep + 'post' + os.sep
    if os.path.exists(content_output):
        shutil.rmtree(content_output)

    cache_dir = os.getcwd() + '_cache' + os.sep
    cache_path = cache_dir + 'historty.json'  # sys.argv[0]
    if not os.path.exists(cache_dir):
        os.mkdir(cache_dir)

    # 配置管理类
    manager = Manager(
        # history_path=root_path + 'a_cache' + os.sep + 'historty.json'
        history_path=cache_path
    )

    # 批量生成ipa
    list_ipa = []
    ipa_floder = root_path + 'a_ipa' + os.sep
    if os.path.exists(ipa_floder):
        list_tmp = []
        ipa_tool = Ipa()
        ipa_tool.list_files(ipa_floder, list_tmp)
        is_have_ipa_floder = False
        for path in list_tmp:
            if path.endswith('.ipa'):
                is_have_ipa_floder = True
                break

        if is_have_ipa_floder == True:
            ipa_dir = app_args.ipa_dir
            ipa_out_floder = ipa_floder + 'files_out'
            if os.path.exists(ipa_out_floder):
                shutil.rmtree(ipa_out_floder)
            if os.path.exists(ipa_dir):
                shutil.rmtree(ipa_dir)
            cmd = 'cd %s && bash ./a_re_sign_full.sh' % (root_path)
            os.system(cmd)
            list_tmp = []
            ipa_tool.list_files(ipa_floder, list_tmp)
            for path in list_tmp:
                if path.endswith('.ipa') and path.rfind('files_out') > -1:
                    list_ipa.append(path)
                    manager.handle_add(app_args, ipa_src_path=path)


    # 增加文件
    app_info = manager.handle_add(app_args)

    # 重建历史md文件
    count = manager.handle_history(
        app_args=app_args,
    )

    # 重建hugo网页
    manager.rebuild_hugo(workspace=root_path)

    # 复制网页文件
    manager.copy_public(
        src_path=root_path + 'public' + os.sep,
        tar_path=copy_public_path
    )

    if len(list_ipa) > 0:
        manager.cos_update(app_args.ipa_dir, 'ios/ipa_hugo')
    # 提交
    message = ''
    if app_info != None:
        message = app_info.identification()

    message = message + app_desc
    manager.git_commit(workspace=root_path, message=message)

    endTime = time.time()
    print("总耗时: %0.2f" % (endTime - startTime))


if __name__ == "__main__":
    main()
